<?php
namespace app\api\controller\mytool;

use app\api\controller\Base;
use app\common\model\user\User as UserModel;
use app\common\model\customer\Street; 

class Mapapi extends Base
{
    /**
     * 产生jwt加密串，参考session
     */
    public function initialize()
    {
        parent::initialize();
        // self::is_login();
    }

    const x_pi = 3.14159265358979324 * 3000.0 / 180.0;
    // π
    const pi = 3.1415926535897932384626;
    // 长半轴
    const a = 6378245.0;
    // 扁率
    const ee = 0.00669342162296594323;

    /**
     * 获取街道列表
     * @return [type] [description]
     */
    public function getstreetlist(){
        $res = Street::getarray();
        return myok($res);
    }

    /**
     * 获取坐标
     * @return [type] [description]
     */
    public function getlocaltion($address)
    {
        $uurl = 'https://apis.map.qq.com/ws/geocoder/v1/?address=' . $address . '&key=' . get_config_value('QQMAPKEY');
        return json_array(self::https_request($uurl), true);
    }

    /**
     * 获取语义化位置信息
     * @return [type] [description]
     */
    public function searchkey()
    {
        $location = input('location');
        if (empty($location)) {
           $location = COMPANYLAT.','.COMPANYLON;
        }
        $searchkey = input('searchkey');
        if (empty($searchkey)) {
            return myerr('请输入关键词');
        }
        $uurl = 'https://apis.map.qq.com/ws/place/v1/search?boundary=nearby('. $location . ',1000,1)&keyword='.self::encodeURI($searchkey).'&key=' . get_config_value('QQMAPKEY') . '&getopi=1&page_size=20';
        try {
            $data = json_array(self::https_request($uurl),true);
        } catch (\Exception $e) {
            return myerr('搜索能力出现问题');
        }
        if(empty($data['count'])){
            return myerr('没有搜到有关信息');
        }
        return myok($data['data']);
    }

    /**
     * 根据经纬度获取语义化定位
     * @return [type] [description]
     */
    public function self_get_opi($lat,$lon){
        $uurl = 'https://apis.map.qq.com/ws/geocoder/v1/?location=' . $lat.','.$lon .'&key=' . get_config_value('QQMAPKEY') . '&getopi=1';
        try {
            $data = json_array(self::https_request($uurl),true);
            if($data['message']=='query ok'){
                $data = $data['result'];
            }
        } catch (\Exception $e) {
            return serr('定位服务出现问题');
        }
        return sok($data);
    }
    /**
     * 获取语义化位置信息
     * @return [type] [description]
     */
    public function getopi()
    {
        $location = input('location');
        if (empty($location)) {
            return myerr('缺少参数');
        }
        $uurl = 'https://apis.map.qq.com/ws/geocoder/v1/?location=' . $location .'&key=' . get_config_value('QQMAPKEY') . '&getopi=1';
        return self::https_request($uurl);
    }

    /**
     * 获取语义化位置信息
     * @return [type] [description]
     */
    public  function getpolygon($id)
    {
        if (empty($id)) {
            return serr('缺少参数');
        }
        // $uurl = 'https://apis.map.qq.com/ws/district/v1/search?keyword=' . $id .'&key=' . get_config_value('QQMAPKEY') . '&get_polygon=2&max_offset=100';
        $uurl = 'https://apis.map.qq.com/ws/district/v1/getchildren?id=' . $id .'&key=' . get_config_value('QQMAPKEY') . '&get_polygon=2&max_offset=100';
        try {
            $data = json_array(self::https_request($uurl),true);
            if($data['message']=='query ok'){
                $data = $data['result'];
            }
        } catch (\Exception $e) {
            return serr('获取区域出现问题');
        }
        return sok($data);
    }

    /**
     * 网址编码
     * @param  [type] $url [description]
     * @return [type]      [description]
     */
    public function encodeURI($url) {
        $unescaped = array(
            '%2D'=>'-','%5F'=>'_','%2E'=>'.','%21'=>'!', '%7E'=>'~',
            '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')'
        );
        $reserved = array(
            '%3B'=>';','%2C'=>',','%2F'=>'/','%3F'=>'?','%3A'=>':',
            '%40'=>'@','%26'=>'&','%3D'=>'=','%2B'=>'+','%24'=>'$'
        );
        $score = array(
            '%23'=>'#'
        );
        return strtr(rawurlencode($url), array_merge($reserved,$unescaped,$score));

    }

    /**
     * 中国正常GCJ02坐标---->百度地图BD09坐标
     * 腾讯地图用的也是GCJ02坐标
     * @param double $lat 纬度
     * @param double $lng 经度
     */
    public static function Convert_GCJ02_To_BD09($lat, $lng)
    {
        $x_pi  = 3.14159265358979324 * 3000.0 / 180.0;
        $x     = $lng;
        $y     = $lat;
        $z     = sqrt($x * $x + $y * $y) + 0.00002 * sin($y * $x_pi);
        $theta = atan2($y, $x) + 0.000003 * cos($x * $x_pi);
        $lng   = $z * cos($theta) + 0.0065;
        $lat   = $z * sin($theta) + 0.006;
        return array('lng' => $lng, 'lat' => $lat);
    }
    
    /**
     * 百度地图BD09坐标---->中国正常GCJ02坐标
     * 腾讯地图用的也是GCJ02坐标
     * @param double $lat 纬度
     * @param double $lng 经度
     * @return array();
     */
    public static function Convert_BD09_To_GCJ02($lat, $lng)
    {
        $x_pi  = 3.14159265358979324 * 3000.0 / 180.0;
        $x     = $lng - 0.0065;
        $y     = $lat - 0.006;
        $z     = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * $x_pi);
        $theta = atan2($y, $x) - 0.000003 * cos($x * $x_pi);
        $lng   = $z * cos($theta);
        $lat   = $z * sin($theta);
        return array('lng' => $lng, 'lat' => $lat);
    }
    /**
     * WGS84转GCJ02(火星坐标系)
     *
     * @param float $lng WGS84坐标系的经度
     * @param float $lat WGS84坐标系的纬度
     * @return array 火星坐标数组
     */
    public static function wgs84ToGcj02 (float $lat,float $lng): array {
        $d_lat = self::transFormLat($lng - 105.0, $lat - 35.0);
        $d_lng = self::transFormLng($lng - 105.0, $lat - 35.0);
        $rad_lat = $lat / 180.0 * self::pi;
        $magic = sin($rad_lat);
        $magic = 1 - self::ee * $magic * $magic;
        $sqrt_magic = sqrt($magic);
        $d_lat = ($d_lat * 180.0) / ((self::a * (1 - self::ee)) / ($magic * $sqrt_magic) * self::pi);
        $d_lng = ($d_lng * 180.0) / (self::a / $sqrt_magic * cos($rad_lat) * self::pi);
        $mg_lat = $lat + $d_lat;
        $mg_lng = $lng + $d_lng;
        return ['lng' => $mg_lng,'lat' => $mg_lat];
    }

    /**
     * 纬度转换
     * @param float $lng
     * @param float $lat
     * @return float|int
     */
    public static function transFormLat (float $lng, float $lat): float {
        $ret = -100.0 + 2.0 * $lng + 3.0 * $lat + 0.2 * $lat * $lat + 0.1 * $lng * $lat + 0.2 * sqrt(abs($lng));
        $ret += (20.0 * sin(6.0 * $lng * self::pi) + 20.0 * sin(2.0 * $lng * self::pi)) * 2.0 / 3.0;
        $ret += (20.0 * sin($lat * self::pi) + 40.0 * sin($lat / 3.0 * self::pi)) * 2.0 / 3.0;
        $ret += (160.0 * sin($lat / 12.0 * self::pi) + 320 * sin($lat * self::pi / 30.0)) * 2.0 / 3.0;
        return $ret;
    }
 
    /**
     * 经度转换
     * @param float $lng
     * @param float $lat
     * @return float
     */
    public static function transFormLng (float $lng, float $lat): float {
        $ret = 300.0 + $lng + 2.0 * $lat + 0.1 * $lng * $lng + 0.1 * $lng * $lat + 0.1 * sqrt(abs($lng));
        $ret += (20.0 * sin(6.0 * $lng * self::pi) + 20.0 * sin(2.0 * $lng * self::pi)) * 2.0 / 3.0;
        $ret += (20.0 * sin($lng * self::pi) + 40.0 * sin($lng / 3.0 * self::pi)) * 2.0 / 3.0;
        $ret += (150.0 * sin($lng / 12.0 * self::pi) + 300.0 * sin($lng / 30.0 * self::pi)) * 2.0 / 3.0;
        return $ret;
    }

    /**
     * 请求
     * @param  [type] $url  [description]
     * @param  [type] $data [description]
     * @return [type]       [description]
     */
    protected function https_request($url, $data = null)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        //下面这行是修改后增加的代码，就是配置设置host访问，发送的数据类型为application/json
        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: ' . strlen($data),
        ));
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }

    /**
     * 判断账号是否登录
     * @return boolean [description]
     */
    private function is_login()
    {
        $data = UserModel::is_sessionlogin();
        if (!$data['code']) {
            $data['options'] = 'relogin';
            json($data)->send();
            exit;
        }
    }
}
